package org.dromara.bean.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.dromara.bean.constant.OrderStatusConstant;
import org.dromara.bean.constant.OrderTypeConstant;
import org.dromara.bean.domain.*;
import org.dromara.bean.domain.vo.Result;
import org.dromara.bean.mapper.HisGoodsDetailsMapper;
import org.dromara.bean.mapper.HisGoodsMapper;
import org.dromara.bean.mapper.HisGoodsOrderMapper;
import org.dromara.bean.mapper.HisRegistrationMapper;
import org.dromara.bean.service.*;
import org.dromara.bean.util.wxApi.WXHandleUtil;
import org.dromara.bean.util.wxApi.WeChatUtil;
import org.dromara.common.core.domain.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jakarta.servlet.ServletInputStream;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description: 微信异步回调地址
 *
 * @author Handy
 * Date: 2024/4/9
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WxNotifyServiceImpl implements IWxNotifyService {

    private final HisRegistrationMapper registrationMapper;

    private final HisGoodsOrderMapper goodsOrderMapper;

    private final HisGoodsMapper goodsMapper;

    private final IBasePaymentLogService paymentLogService;

    private final WXHandleUtil wxHandleUtil;

    private final IBaseMemberRefundService iBaseMemberRefundService;

    private final IHisMemberService memberService;

    private final IHisDepService doctorService;

    private final HisGoodsDetailsMapper detailsMapper;

    private final IHisRegistrationService iRegisterService;

    private final IHisGoodsOrderService iHisGoodsOrderService;



    @Override
    public String wxNotify(HttpServletRequest request) {
        String returnXml;
        Map<String, String> map = new HashMap<>();
        log.warn("接受参数：【{}】", map);
        try {

            ServletInputStream instream =  request.getInputStream();
            R<?> resultMag = WeChatUtil.payNotifyResult(instream);
            log.warn("订单回调：【{}】", resultMag);
            // TODO 查询日志 修改日志记录 根据日志记录再各自走业务
            HisPaymentLog hisPaymentLog = paymentLogService.updatePaymentLog(resultMag);
            //挂号订单
            iRegisterService.updateRegistration(resultMag);

            iHisGoodsOrderService.updateOrder(resultMag);

        } catch (Exception e) {
            log.error("payNotify error", e);
        } finally {
            map.put("return_code", "SUCCESS");
            map.put("return_msg", "OK");
            returnXml = WeChatUtil.resultXmlData(map);
            return returnXml;
        }
    }

    @Override
    public String wechatRefund(HttpServletRequest request, HttpServletResponse response) {
        try {
            InputStream is = request.getInputStream();
            //将InputStream转换成String
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line = null;
            try {
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
            } catch (IOException e) {
                log.error("wechatRefund error", e);
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    log.error("wechatRefund error", e);
                }
            }
            String resXml = sb.toString();
            log.warn("微信退款异步通知请求包------");
            log.warn(resXml);
                return wechatRefund(resXml);
        } catch (Exception e) {
            log.error("微信退款回调通知失败", e);
            String result = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml> ";
            return result;
        }
    }

    private String wechatRefund(String xmlStr) {
        try {
            JSONObject map = JSONObject.parseObject(xmlStr);
            if (null == map || map.size() == 0) {
                log.warn("解密异常");
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
            }
            log.warn("解密回文：【{}】", map);
            String associatedData = map.getJSONObject("resource").getString("associated_data");
            String nonce = map.getJSONObject("resource").getString("nonce");
            String ciphertext = map.getJSONObject("resource").getString("ciphertext");
            String decryptToString = wxHandleUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
                    nonce.getBytes(StandardCharsets.UTF_8),
                    ciphertext);
            JSONObject recource = JSONObject.parseObject(decryptToString);
            // 退款单号
            String outRefundNo = recource.getString("out_refund_no");
            if (null == outRefundNo) {
                log.warn("商户退款单号为空");
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
            }
            // outRefundNo 实际入参是 主键id 应该是一个编号
            HisMemberRefund memberRefund = iBaseMemberRefundService.getById(outRefundNo);
            Date date = new Date();
            // 后续所有的支付走这个判断
            switch (memberRefund.getOrderType()) {
                case OrderTypeConstant.ORDER_REGISTRATION_TREAT:
                    // 挂号
                    memberRefund.setStatus("2")
                            .setUpdateTime(date);
                    iBaseMemberRefundService.updateById(memberRefund);
                    HisRegistration registration = registrationMapper.selectById(memberRefund.getOrderTreatId());
                    registration.setStatus(OrderStatusConstant.REGISTER_REFUND);
                    registrationMapper.updateById(registration);
                    break;
                case OrderTypeConstant.ORDER_COMMODITY_TREAT:
                    memberRefund.setStatus("2")
                        .setUpdateTime(date);
                    iBaseMemberRefundService.updateById(memberRefund);
                    HisGoodsOrder goodsOrder = goodsOrderMapper.selectById(memberRefund.getOrderTreatId());
                    goodsOrder.setStatus(OrderStatusConstant.SHOP_REFUND);
                    goodsOrderMapper.updateById(goodsOrder);

                    List<HisGoodsDetails> hisGoodsDetails = detailsMapper.selectList(new LambdaQueryWrapper<HisGoodsDetails>()
                        .eq(HisGoodsDetails::getOrderId, goodsOrder.getId()));
                    for (HisGoodsDetails details : hisGoodsDetails) {
                        HisGoods hisGoods = goodsMapper.selectById(details.getGoodsId());
                        hisGoods.setSales(hisGoods.getSales() - details.getCount());
                    }
                    detailsMapper.updateBatchById(hisGoodsDetails);
                    break;
                default:
                    log.warn("不支持的单据类型 memberRefundId = {}", memberRefund.getId());
                    break;
            }
            log.warn("\n\t----------------------------------------------------------\n\t" +
                    "订单退款成功" +
                    "\n\t----------------------------------------------------------");

            return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        } catch (Exception e) {
            log.error("退款回调失败 wechatRefund error", e);
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
        }
    }
}
